<template>
  <div class="table-search">
    <el-collapse-transition>
      <div v-if="searchOptions.show">
        <el-form :inline="true" :model="searchSource.inModel"  @keyup.enter.native="searchHandle(1)" class="demo-form-inline">
          <template v-for="(_item, _index) in searchSource.operations">
            <el-form-item :label="_item.name ? _item.name + ':' : ''" v-bind:key="_index" class="table-search-operation__item">
              <!-- 占位 -->
              <span v-if="_item.type === 'place'" class="table-search-operation__item_span" :style="{ width: _item.width }"></span>
              <!-- 文本框控件 -->
              <el-input v-if="_item.type === 'text'"
               v-model.trim="_item.value" :key="_item.key" :disabled="_item.disabled" :maxlength="_item.length || 15"
               :placeholder="_item.placeholder || ''" :style="{ width: _item.width }" :size="searchOptions.size"
               @change="changeHandle(_item, _index)" @focus="showHandle(_item, _index, $event)" @clear="clearHandle(_item, _index)"
                clearable>
              </el-input>
              <!-- 复选框组控件 -->
              <el-checkbox-group v-if="_item.type === 'checkbox'"
               v-model.trim="_item.value" :disabled="_item.disabled" :size="searchOptions.size"
               @change="changeHandle(_item, _index)">
                <template v-for="item in _item.list">
                  <el-checkbox :key="item.key" :label="item.key">{{ item.value }}</el-checkbox>
                </template>
              </el-checkbox-group>
              <!-- 单选框组控件 -->
              <el-radio-group v-if="_item.type === 'radio'"
               v-model.trim="_item.value" :disabled="_item.disabled" :size="searchOptions.size"
               @change="changeHandle(_item, _index)">
                <template v-for="item in _item.list">
                  <el-radio :key="item.key" :label="item.key">{{ item.value }}</el-radio>
                </template>
              </el-radio-group>
              <!-- 日期控件 -->
              <!-- 开始日期到结束日期 -->
              <el-date-picker v-if="_item.type === 'daterange'" :style="{ width: _item.width || '200px' }"
                v-model.trim="_item.value" value-format="yyyy-MM-dd" :disabled="_item.disabled"
                :size="searchOptions.size" :picker-options="datePickerOptions"
                type="daterange" start-placeholder="开始日期" range-separator="-" end-placeholder="结束日期"
                @change="changeHandle(_item, _index)" unlink-panels clearable>
              </el-date-picker>
              <!-- 开始月份到结束月份 -->
              <el-date-picker v-if="_item.type === 'monthrange'" :style="{ width: _item.width || '200px' }"
                v-model.trim="_item.value" value-format="yyyy-MM" :disabled="_item.disabled"
                :size="searchOptions.size" :picker-options="monthPickerOptions"
                type="monthrange" start-placeholder="开始月份" range-separator="-" end-placeholder="结束月份"
                @change="changeHandle(_item, _index)" unlink-panels clearable>
              </el-date-picker>
              <!-- 选择日期 -->
              <el-date-picker v-if="_item.type === 'date'" :style="{ width: _item.width || '90px' }"
                v-model.trim="_item.value" value-format="yyyy-MM-dd" :disabled="_item.disabled"
                :type="_item.type" :size="searchOptions.size" placeholder="选择日期"
                @change="changeHandle(_item, _index)" unlink-panels clearable>
              </el-date-picker>
              <!-- 选择年份 -->
              <el-date-picker v-if="_item.type === 'year'" :style="{ width: _item.width || '90px' }"
                v-model.trim="_item.value" value-format="yyyy" :disabled="_item.disabled"
                :type="_item.type" :size="searchOptions.size" placeholder="选择年份"
                @change="changeHandle(_item, _index)" unlink-panels clearable>
              </el-date-picker>
              <!-- 选择月份 -->
              <el-date-picker v-if="_item.type === 'month'" :style="{ width: _item.width || '90px' }"
                v-model.trim="_item.value" value-format="yyyy-MM" :disabled="_item.disabled"
                :type="_item.type" :size="searchOptions.size" placeholder="选择月份"
                @change="changeHandle(_item, _index)" unlink-panels clearable>
              </el-date-picker>
              <!-- 下拉框控件 -->
              <!-- 下拉框 -->
              <el-select v-if="_item.type === 'select'" :style="{ width: _item.width || '90px' }"
                v-model.trim="_item.value" :disabled="_item.disabled" :multiple="_item.multiple"
                :filterable="_item.filterable" :collapse-tags="_item.collapseTags"
                :size="searchOptions.size" :placeholder="_item.placeholder || '请选择'"
                @change="changeHandle(_item, _index, _item.list.filter(item => {return item.key == _item.value}))" clearable>
                <el-option v-for="item in _item.list" :key="item.key" :label="item.key" :value="item.value"></el-option>
              </el-select>
              <!-- 下拉年框 -->
              <el-select v-if="_item.type === 'selectyear'" :style="{ width: _item.width || '90px' }"
                v-model.trim="_item.value" :disabled="_item.disabled"
                :size="searchOptions.size" :placeholder="_item.placeholder || '请选择'"
                @change="changeHandle(_item, _index)" clearable>
                <el-option v-for="item in formatYear()" :key="item.key" :label="item.key" :value="item.value"></el-option>
              </el-select>
              <!-- 下拉月框 -->
              <el-select v-if="_item.type === 'selectmonth'" :style="{ width: _item.width || '90px' }"
                v-model.trim="_item.value" :disabled="_item.disabled"
                :size="searchOptions.size" :placeholder="_item.placeholder || '请选择'"
                @change="changeHandle(_item, _index)" clearable>
                <el-option v-for="item in _item.list || formatMonth()" :key="item.key" :label="item.key" :value="item.value"></el-option>
              </el-select>
              <!-- 下拉月区间框 -->
              <template v-if="_item.type === 'selectmonthrange'">
                <el-select :style="{ width: _item.width || '90px' }"
                  v-model.trim="_item.value[0]" :disabled="_item.disabled"
                  :size="searchOptions.size" :placeholder="_item.placeholder || '请选择'"
                  @change="changeHandle(_item, _index)" clearable>
                  <el-option v-for="item in _item.list || formatMonth()" :key="item.key" :label="item.key" :value="item.value"></el-option>
                </el-select>
                <label style="fontSize:12px;color:#7B7F83">{{ _item.go || '至' }}</label>
                <el-select :style="{ width: _item.width || '90px' }"
                  v-model.trim="_item.value[1]" :disabled="_item.disabled"
                  :size="searchOptions.size" :placeholder="_item.placeholder || '请选择'"
                  @change="changeHandle(_item, _index)" clearable>
                  <el-option v-for="item in _item.list || formatMonth()" :key="item.key" :label="item.key" :value="item.value"></el-option>
                </el-select>
              </template>
            </el-form-item>
          </template>
          <template v-if="searchOptions.init">
            <el-form-item>
              <el-button type="primary" icon="el-icon-search" :plain="searchOptions.plain" :size="searchOptions.size" v-prevent-re-click
               @click="searchHandle(1)">
                查询
              </el-button>
              <el-button type="primary" icon="el-icon-refresh" :plain="searchOptions.plain" :size="searchOptions.size" v-prevent-re-click
               @click="resetHandle()">
                重置
               </el-button>
              <slot name="table-search_behind"></slot>
            </el-form-item>
          </template>
          <template v-else>
            <el-form-item><slot name="table-search_customer"></slot></el-form-item>
          </template>
        </el-form>
      </div>
    </el-collapse-transition>
  </div>
</template>

<script>
export default {
  props: {
    // 搜索设置
    searchOptions: {
      type: Object,
      default: () => ({
        show: true, // 搜索条件是否显示
        init: true, // 初始化资源
        size: 'small', // 尺寸medium|small|mini
        plain: false // 是否朴素
      })
    },
    // 搜索配置
    searchSource: {
      type: Object,
      default: () => ({
        // 初始模型
        inModel: {
          type: Object
        },
        // 配置列表
        operations: {
          type: Array,
          required: true,
          default: () => [{
            name: '名称',
            key: '查询值绑定字段',
            value: '默认值',
            type: '表单组件类型', // place占位符，其他类型参照element-ui文档
            disabled: false, // 表单组件是否禁用
            placeholder: '表单组件提示语',
            width: '100px', // 表单组件宽度
            length: 15, // 输入框最大输入长度
            multiple: false, // 下拉框是否多选
            collapseTags: false, // 下拉框所选时是否将选中值按文字的形式展示
            filterable: false, // 下拉框是否可搜索
            list: { // 复选框、单选框或者下拉框
              type: Array,
              default: () => [{
                key: 'key',
                value: 'value'
              }]
            }
          }]
        }
      })
    }
  },
  data() {
    return {
      datePickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            let end = new Date()
            let start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            let end = new Date()
            let start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近三个月',
          onClick(picker) {
            let end = new Date()
            let start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            picker.$emit('pick', [start, end])
          }
        }]
      },
      monthPickerOptions: {
        shortcuts: [{
          text: '本月',
          onClick(picker) {
            picker.$emit('pick', [new Date(), new Date()])
          }
        }, {
          text: '今年至今',
          onClick(picker) {
            let end = new Date()
            let start = new Date(new Date().getFullYear(), 0)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近六个月',
          onClick(picker) {
            let end = new Date()
            let start = new Date()
            start.setMonth(start.getMonth() - 6)
            picker.$emit('pick', [start, end])
          }
        }]
      },
      formatYear() {
        let dateList = []
        for (let i = 0; i < 7; i++) {
          dateList.push(new Date().getFullYear() + i - 5)
        }
        let select = []
        dateList.forEach(item => {
          let obj = {
            key: item,
            value: item
          }
          select.push(obj)
        })
        return select.reverse()
      },
      formatMonth() {
        return [
          { value: '01', key: '一月' },
          { value: '02', key: '二月' },
          { value: '03', key: '三月' },
          { value: '04', key: '四月' },
          { value: '05', key: '五月' },
          { value: '06', key: '六月' },
          { value: '07', key: '七月' },
          { value: '08', key: '八月' },
          { value: '09', key: '九月' },
          { value: '10', key: '十月' },
          { value: '11', key: '十一月' },
          { value: '12', key: '十二月' }
        ]
      }
    }
  },
  created() {
    this.searchSource.operations.forEach(item => {
      if ((item.type === 'checkbox' || item.type === 'selectmonthrange') && item.value === undefined) {
        item.value = []
      }
    })
  },
  computed: {},
  methods: {
    // 表单组件值发生变化
    changeHandle(_item, _index, _value) {
      // 每个条件框数据发生变化都会执行该方法
      this.searchSource.operations.forEach((item, index) => {
        if (index === _index || _index === 'all') {
          if (_item.event !== 'focus') {
            if (_item.type.indexOf('range') !== -1) {
              let newKey = _item.key.charAt(0).toUpperCase() + _item.key.slice(1)
              this.$set(this.searchSource.inModel, 'min' + newKey, _item.value ? _item.value[0] : null)
              this.$set(this.searchSource.inModel, 'max' + newKey, _item.value ? _item.value[1] : null)
              this.$set(this.searchSource.inModel, _item.key, _item.value ? _item.value : [])
            } else {
              this.$set(this.searchSource.inModel, _item.key, _item.value)
            }
          }
        }
      })
      if (_index !== 'all' && (_item.type === 'select' || _item.type === 'radio') && _item.event === 'change') {
        this.$emit('changeHandle', { 'backData': _item, _index }, _value)
      }
    },
    showHandle(_item, _index, e) {
      if (_item.event === 'focus') {
        e.target.blur()
        // input输入框 获取焦点父组件传递callback时间
        // input 类型是text ,event 是focus才会执行
        this.$emit('callback', { 'backData': _item, _index })
      }
    },
    // 表单组件清除
    clearHandle(_item, _index) {
      if (_item.event === 'focus') {
        for (let field in _item) {
          if (this.searchSource.inModel[_item[field]]) {
            this.$set(this.searchSource.inModel, _item[field], '')
          }
        }
        this.$emit('clearHandle', { 'backData': _item, _index })
      }
    },
    // 搜索按钮
    searchHandle(page) {
      this.$emit('searchHandle', { 'backData': this.searchSource.inModel, page })
    },
    // 重置按钮
    resetHandle() {
      this.searchSource.operations.forEach(item => {
        if (item.multiple) {
          this.$set(item, 'value', [])
        } else {
          this.$set(item, 'value', '')
        }
      })
      for (let field in this.searchSource.inModel) {
        this.$set(this.searchSource.inModel, field, '')
      }
      this.$emit('resetHandle', { 'backData': this.searchSource.inModel })
    }
  }
}
</script>

<style lang="scss" scoped>
.table-search {
  background: #fff;
  padding: 0 10px 5px;
  position: relative;
  .el-form-item {
    margin-bottom: 0px;
  }
  &-operation {
    &__item {
      margin-left: 0px;
      &_span {
        display: inline-block;
      }
    }
  }
}
</style>
